package com.kehutong.house.admin;

import com.kehutong.common.DoveClient;
import com.kehutong.common.util.Token;
import com.kehutong.house.constant.SupplierConstant;
import com.kehutong.house.entity.*;
import com.kehutong.house.enums.AccessControlStatus;
import com.kehutong.house.enums.DeviceManagementType;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.connection.ThreadLocalCache;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@MvcAction
@ReqMapping("/admin/management")
public class DeviceManagementController {
    @Inject
    private JdbcSession jdbcSession;
    @Inject
    private DoveClient doveClient;
    private Logger log= LoggerFactory.getLogger(DeviceManagementController.class);
    public final static String[] EXCEL_IMPORT_HEADER = {"设备类型名称"};

    /**
     * 设备列表，客户通用
     * @param token
     * @param jsonObject
     * @return
     */
    @ReqMapping("/list")
    public Object list(Token token, JSONObject jsonObject) {
        FindPage<DeviceManagement> find = jdbcSession.findPage(DeviceManagement.class);
        String equipmentName=jsonObject.getString("equipmentName");
        String communityIds=jsonObject.getString("communityIds");
        String equipmentType=jsonObject.getString("equipmentType");
        String bindingState=jsonObject.getString("bindingState");
        String state=jsonObject.getString("state");
        if(Objects.nonEmpty(equipmentName)){
            equipmentName=equipmentName.trim();
            Pattern r = Pattern.compile("^\\d+$");
            Matcher m = r.matcher(equipmentName);
            if(equipmentName.indexOf("SB")!=-1||m.find()){
                find.like("khtDeviceNo",equipmentName);
            }else{
                find.like("equipmentName",equipmentName);
            }
        }
        find.eq("deleted", false);
        if(Objects.nonEmpty(communityIds)){
            JSONArray communityIdArray=jsonObject.getJSONArray("communityIds");
            find.eq("corpId",communityIdArray.get(0).toString());
            find.eq("communityId",communityIdArray.get(1).toString());
        }
        if(Objects.nonEmpty(equipmentType)){
            find.eq("equipmentType",equipmentType);
        }
        if(Objects.nonEmpty(bindingState)){
            find.eq("bindingState",bindingState);
        }
        if(Objects.nonEmpty(state)){
            find.eq("state",state.equals("false")?false:true);
        }
        find.order("bindingState","ASC").order("createTime", "DESC");
        Page<DeviceManagement>page=find.exe();
        page.getList().forEach(item->{
            if(Objects.nonEmpty(item.getSupplierId())){
                Supplier supplier=jdbcSession.findById(Supplier.class,item.getSupplierId());
                if(supplier!=null){
                    item.setSupplierName(supplier.getName());
                }
            }
            if(DeviceManagementType.BOUND.getId().equals(item.getBindingState())){
                if(item.getHeartBeatTime()==null){
                    item.setOnLine(false);
                }else{
                    item.setOnLine(System.currentTimeMillis()-item.getHeartBeatTime().getTime()<item.getHbinterval()*2*1000?true:false); //设备是否在线
                }
            }
        });
        return page;
    }

    /**
     * 授权的设备列表，物业管理员用
     * @param token
     * @param jsonObject
     * @return
     */
    @ReqMapping("/authList")
    public Object authList(Token token, JSONObject jsonObject) {
        String corpId=token.getCompanyNo();
        FindPage<DeviceManagement> find = jdbcSession.findPage(DeviceManagement.class);
        String equipmentName=jsonObject.getString("equipmentName");
        String communityId=jsonObject.getString("communityId");
        String equipmentType=jsonObject.getString("equipmentType");
        String bindingState=jsonObject.getString("bindingState");
        String state=jsonObject.getString("state");
        if(Objects.nonEmpty(equipmentName)){
            equipmentName=equipmentName.trim();
            Pattern r = Pattern.compile("^\\d+$");
            Matcher m = r.matcher(equipmentName);
            if(equipmentName.indexOf("SB")!=-1||m.find()){
                find.like("khtDeviceNo",equipmentName);
            }else{
                find.like("equipmentName",equipmentName);
            }
        }
        find.eq("deleted", false);
        find.eq("bindingState",DeviceManagementType.BOUND.getId());
        find.eq("corpId",corpId);
        if(Objects.nonEmpty(communityId)){
            find.eq("communityId",communityId);
        }
        if(Objects.nonEmpty(equipmentType)){
            find.eq("equipmentType",equipmentType);
        }
        if(Objects.nonEmpty(state)){
            find.eq("state",state.equals("false")?false:true);
        }
        find.order("bindingState","ASC").order("createTime", "DESC");
        Page<DeviceManagement>page=find.exe();
        page.getList().forEach(item->{
            if(Objects.nonEmpty(item.getSupplierId())){
                Supplier supplier=jdbcSession.findById(Supplier.class,item.getSupplierId());
                if(supplier!=null){
                    item.setSupplierName(supplier.getName());
                }
            }
            if(DeviceManagementType.BOUND.getId().equals(item.getBindingState())){
                if(item.getHeartBeatTime()==null){
                    item.setOnLine(false);
                }else{
                    item.setOnLine(System.currentTimeMillis()-item.getHeartBeatTime().getTime()<item.getHbinterval()*2*1000?true:false); //设备是否在线
                }
            }
            //门禁用户
            List<AccessControlAuth> accessControlAuthList=jdbcSession.findArray(AccessControlAuth.class)
                    .eq("deviceId",item.getId())
                    .eq("deleted",false)
                    .eq("authStatus", AccessControlStatus.IN_FORCE.getId())
                    .exe();
            item.setResidentCount(accessControlAuthList.size());
        });
        return page;
    }
    @ReqMapping("/listAll")
    public Object listAll(JSONObject jsonObject) throws Exception {
        return jdbcSession.findArray(EquipmentClassify.class)
                .eq("deleted", false)
                .eq("typeStatus", true)
                .order("createTime", "DESC")
                .exe();
    }

    @ReqMapping("/supplierListAll")
    public Object supplierListAll() throws Exception {
        return jdbcSession.findArray(Supplier.class)
                .eq("deleted", false)
                .eq("status", true)
                .order("createTime", "DESC")
                .exe();
    }


    @Bean(copy=true)
    @ReqMapping("/update")
    public Object update(DeviceManagement deviceManagement, Token token) throws Exception {
        JSONObject msgJson=new JSONObject();//返回给前端
        String msg=null;//前端提示语
        try {
            DeviceManagement device=jdbcSession.findById(DeviceManagement.class,deviceManagement.getId());
            if(Objects.isNull(device)){
                return Result.error(0, "当前设备不存在，请修改后重试");
            }
            String opType=null;  //接口操作方式
            String interfaceName=null;
            //如果当前设备没有绑定
            if(DeviceManagementType.NBOUND.getId().equals(device.getBindingState())){
                if(DeviceManagementType.BOUND.getId().equals(deviceManagement.getBindingState())){
                    opType="1";//调用绑定接口新增绑定
                    interfaceName="绑定";
                }
            }else{
                //当前设备是绑定的
                if(DeviceManagementType.NBOUND.getId().equals(deviceManagement.getBindingState())){
                    opType="3"; //解除绑定
                    interfaceName="解除绑定";
                }else{
                    //机号改变、绑定
                    if(!device.getDeviceNo().equals(deviceManagement.getDeviceNo())){
                        opType="1";//调用绑定接口新增绑定
                        interfaceName="绑定";
                    }else{ //机号不变、序列号发生变化更新
                        if(!device.getDeviceSeq().equals(deviceManagement.getDeviceSeq())){
                            opType="2"; //更新绑定
                            interfaceName="更新";
                        }
                    }
                }
            }
            if(opType!=null){
                SupplierConfig supplierConfig=jdbcSession.findOne(SupplierConfig.class).eq("supplierId",deviceManagement.getSupplierId()).exe();
                if(supplierConfig==null){
                    return Result.error(0, "请配置设备供应商");
                }
                String method="managerDoorInfo"; String url=supplierConfig.getServiceUrl()+method; //接口请求地址
                log.info("设备绑定请求地址=========="+url);
                String finalOpType = opType;
                JSONObject result = doveClient.post(url, http->{
                    JSONObject body = new JSONObject();
                    body.put("opType", finalOpType);
                    body.put("doorNo", deviceManagement.getDeviceNo());
                    body.put("doorName", deviceManagement.getEquipmentName());
                    body.put("doorSeq", deviceManagement.getDeviceSeq());
                    body.put("doorType","1");
                    body.put("areaId",deviceManagement.getCorpId());
                    body.put("ext",supplierConfig.getExt());
                    http.setBody(body.toString());
                });

                log.info("调用auth-api服务返回=========="+result);
                if(result.getIntValue("code")==200){  //接口调用成功
                    JSONObject dataJson=result.getJSONObject("data");
                    String errcode=dataJson.getString("errcode");
                    msg=dataJson.getString("msg");  //接口返回的错误
                    if(!"0".equals(errcode)){
                       msgJson.put("msg",msg);
                    }else{
                        jdbcSession.updateById(deviceManagement);
                        if("3".equals(opType)){
                            msg="设备从中间件"+interfaceName+"成功";
                        }else{
                            msg="设备"+interfaceName+"到中间件成功";
                        }
                        msgJson.put("msg",msg);
                        //设备配置时间组
                        if(opType=="1"){
                            addDeviceTimeGroup(deviceManagement,supplierConfig.getExt(),supplierConfig.getServiceUrl());
                        }
                    }
                    return Result.success(msg,msgJson);
                }else{
                    return Result.error(0, "调用接口失败");
                }
            }else{
                jdbcSession.updateById(deviceManagement);
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            throw e;
        }
        msg="设备本地基本信息更新成功";
        msgJson.put("msg",msg);
        return Result.success(msg,msgJson);
    }
    @Bean(copy=true)
    @ReqMapping("/enableDevice")
    public Object enableDevice(JSONObject jsonObject) throws Exception {
        JSONArray jsonArray=jsonObject.getJSONArray("ids");
        for (int i = 0; i < jsonArray.size(); i++) {
            String id=jsonArray.get(i).toString();
            DeviceManagement device=jdbcSession.findById(DeviceManagement.class,id);
            device.setState(true);
            jdbcSession.updateById(device);
        }
        return Result.success();
    }
    @Bean(copy=true)
    @ReqMapping("/disableDevice")
    public Object disableDevice(JSONObject jsonObject) throws Exception {
        JSONArray jsonArray=jsonObject.getJSONArray("ids");
        for (int i = 0; i < jsonArray.size(); i++) {
            String id=jsonArray.get(i).toString();
            DeviceManagement device=jdbcSession.findById(DeviceManagement.class,id);
            device.setState(false);
            jdbcSession.updateById(device);
        }
        return Result.success();
    }
    @Bean(newInstance=true, copy=true)
    @ReqMapping("/save")
    public Object save(DeviceManagement deviceManagement) throws Exception{
        if(Objects.isNull(deviceManagement)){
            return Result.error(0, "参数不能null，请修改后重试");
        }
        if(Objects.isEmpty(deviceManagement.getCommunityIds())){
            return Result.error(0, "请选择小区");
        }
        deviceManagement.setCorpId(deviceManagement.getCommunityIds().get(0));
        deviceManagement.setCommunityId(deviceManagement.getCommunityIds().get(1));
        List<DeviceManagement>deviceManagementList=jdbcSession.findArray(DeviceManagement.class).order("khtDeviceNo","DESC").exe();
        if(!Objects.nonEmpty(deviceManagementList)){
            deviceManagement.setKhtDeviceNo(SupplierConstant.KHT_DEVICE_No);
        }else{
            String endKhtDeviceNo=deviceManagementList.get(0).getKhtDeviceNo();
            String newKhtDeviceNo=endKhtDeviceNo.substring(0,2)+(Integer.valueOf(endKhtDeviceNo.substring(2))+1);
            deviceManagement.setKhtDeviceNo(newKhtDeviceNo);
        }
        EquipmentClassify equipmentClassify=jdbcSession.findById(EquipmentClassify.class,deviceManagement.getEquipmentType());
        deviceManagement.setDeviceClassifyName(equipmentClassify.getDeviceClassifyName());
        ThreadLocalCache.current().setCorpId(deviceManagement.getCorpId());
        Community community=jdbcSession.findById(Community.class,deviceManagement.getCommunityId());
        ThreadLocalCache.current().setCorpId(null);
        deviceManagement.setCommunityName(community.getName());
        jdbcSession.insert(deviceManagement);
        return Result.success(deviceManagement);
    }
    @ReqMapping("/get")
    public Object get(DeviceManagement type) {
        return Result.success(type);
    }

    private void addDeviceTimeGroup(DeviceManagement deviceManagement,String ext,String serviceUrl){
        try {
            String method="timeGroup";
            String opType="1"; //1添加
            String url=serviceUrl+method; //接口请求地址
            JSONObject result = doveClient.post(url, http->{
                JSONObject body = new JSONObject();
                body.put("opType", opType);
                body.put("doorNo", deviceManagement.getDeviceNo());
                body.put("timeNo", SupplierConstant.TIME_NO);
                body.put("timeName",SupplierConstant.TIME_NAME);
                body.put("week",SupplierConstant.WEEK);
                body.put("areaId",deviceManagement.getCorpId());
                body.put("ext",ext);
                body.put("beginTime",SupplierConstant.BEGIN_TIME);
                body.put("endTime",SupplierConstant.END_TIME);
                http.setBody(body.toString());
            });
            log.info("调用时间组接口返回json:"+result.toJSONString());
        } catch (Exception e) {
            log.error(e.getMessage()+"设备添加时间组出现异常",e);
        }
    }
    //企微和小程序是否有权限显示门禁
    @ReqMapping("/deviceDisplayed")
    public Object deviceDisplayed(JSONObject params) throws Exception {
        String companyNo = params.getString("companyNo");
        if (Objects.isEmpty(companyNo)) {
            return Result.error(0, "公司编号不能为空!");
        }
        FindPage<DeviceManagement> find = jdbcSession.findPage(DeviceManagement.class);
        find.eq("deleted", false);
        find.eq("corpId",companyNo);
        Page<DeviceManagement>page=find.exe();
        boolean flag = false;
        if(page.getList().size()>0){
            flag = true;
        }
        return Result.success(flag);
    }
}
